using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
using FileStorageService.Files.Enums;
using FileStorageService.Constants;

namespace FileStorageService.Files;

/// <summary>
/// 文件实体
/// </summary>
public class File : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
    /// <summary>
    /// 租户ID
    /// </summary>
    public virtual Guid? TenantId { get; set; }

    /// <summary>
    /// 文件名（包含扩展名）
    /// </summary>
    [Required]
    [StringLength(FileStorageConsts.MaxFileNameLength)]
    public virtual string FileName { get; protected set; } = string.Empty;

    /// <summary>
    /// 文件原始名称
    /// </summary>
    [Required]
    [StringLength(FileStorageConsts.MaxFileNameLength)]
    public virtual string OriginalFileName { get; protected set; } = string.Empty;

    /// <summary>
    /// 文件大小（字节）
    /// </summary>
    public virtual long FileSize { get; protected set; }

    /// <summary>
    /// 文件MIME类型
    /// </summary>
    [StringLength(200)]
    public virtual string? MimeType { get; protected set; }

    /// <summary>
    /// 文件MD5哈希值
    /// </summary>
    [StringLength(32)]
    public virtual string? FileHash { get; protected set; }

    /// <summary>
    /// 文件路径
    /// </summary>
    [StringLength(FileStorageConsts.MaxFilePathLength)]
    public virtual string? FilePath { get; protected set; }

    /// <summary>
    /// 文件描述
    /// </summary>
    [StringLength(FileStorageConsts.MaxFileDescriptionLength)]
    public virtual string? Description { get; protected set; }

    /// <summary>
    /// 文件类型
    /// </summary>
    public virtual FileType FileType { get; protected set; }

    /// <summary>
    /// 存储提供者
    /// </summary>
    public virtual StorageProvider StorageProvider { get; protected set; }

    /// <summary>
    /// 存储容器名称
    /// </summary>
    [StringLength(100)]
    public virtual string? ContainerName { get; protected set; }

    /// <summary>
    /// 缩略图路径
    /// </summary>
    [StringLength(FileStorageConsts.MaxFilePathLength)]
    public virtual string? ThumbnailPath { get; protected set; }

    /// <summary>
    /// 上传用户ID
    /// </summary>
    public virtual Guid? UploaderUserId { get; protected set; }

    /// <summary>
    /// 文件是否公开
    /// </summary>
    public virtual bool IsPublic { get; protected set; } = false;

    /// <summary>
    /// 文件是否已删除
    /// </summary>
    public new virtual bool IsDeleted { get; protected set; } = false;

    /// <summary>
    /// 文件下载次数
    /// </summary>
    public virtual int DownloadCount { get; protected set; } = 0;

    /// <summary>
    /// 文件标签（JSON格式）
    /// </summary>
    public virtual string? Tags { get; protected set; }

    /// <summary>
    /// 文件元数据（JSON格式）
    /// </summary>
    public virtual string? Metadata { get; protected set; }

    protected File()
    {
    }

    public File(
        Guid id,
        string fileName,
        string originalFileName,
        long fileSize,
        FileType fileType,
        StorageProvider storageProvider,
        Guid? tenantId = null) : base(id)
    {
        SetFileName(fileName);
        SetOriginalFileName(originalFileName);
        SetFileSize(fileSize);
        FileType = fileType;
        StorageProvider = storageProvider;
        TenantId = tenantId;
    }

    /// <summary>
    /// 更新文件信息
    /// </summary>
    public File UpdateInfo(string? description = null, bool? isPublic = null, string? tags = null)
    {
        Description = description;
        if (isPublic.HasValue)
        {
            IsPublic = isPublic.Value;
        }
        Tags = tags;

        return this;
    }

    /// <summary>
    /// 设置文件名
    /// </summary>
    public File SetFileName(string fileName)
    {
        FileName = Check.NotNullOrWhiteSpace(fileName, nameof(fileName), maxLength: FileStorageConsts.MaxFileNameLength);
        return this;
    }

    /// <summary>
    /// 设置原始文件名
    /// </summary>
    public File SetOriginalFileName(string originalFileName)
    {
        OriginalFileName = Check.NotNullOrWhiteSpace(originalFileName, nameof(originalFileName), maxLength: FileStorageConsts.MaxFileNameLength);
        return this;
    }

    /// <summary>
    /// 设置文件大小
    /// </summary>
    public File SetFileSize(long fileSize)
    {
        FileSize = Check.Range(fileSize, nameof(fileSize), 1, long.MaxValue);
        return this;
    }

    /// <summary>
    /// 设置MIME类型
    /// </summary>
    public File SetMimeType(string? mimeType)
    {
        MimeType = Check.Length(mimeType, nameof(mimeType), maxLength: 200);
        return this;
    }

    /// <summary>
    /// 设置文件哈希
    /// </summary>
    public File SetFileHash(string? fileHash)
    {
        FileHash = Check.Length(fileHash, nameof(fileHash), maxLength: 32);
        return this;
    }

    /// <summary>
    /// 设置文件路径
    /// </summary>
    public File SetFilePath(string? filePath)
    {
        FilePath = Check.Length(filePath, nameof(filePath), maxLength: FileStorageConsts.MaxFilePathLength);
        return this;
    }

    /// <summary>
    /// 设置缩略图路径
    /// </summary>
    public File SetThumbnailPath(string? thumbnailPath)
    {
        ThumbnailPath = Check.Length(thumbnailPath, nameof(thumbnailPath), maxLength: FileStorageConsts.MaxFilePathLength);
        return this;
    }

    /// <summary>
    /// 设置存储容器名称
    /// </summary>
    public File SetContainerName(string? containerName)
    {
        ContainerName = Check.Length(containerName, nameof(containerName), maxLength: 100);
        return this;
    }

    /// <summary>
    /// 增加下载次数
    /// </summary>
    public File IncrementDownloadCount()
    {
        DownloadCount++;
        return this;
    }

    /// <summary>
    /// 标记为已删除
    /// </summary>
    public File MarkAsDeleted()
    {
        IsDeleted = true;
        return this;
    }

    /// <summary>
    /// 恢复删除状态
    /// </summary>
    public File Restore()
    {
        IsDeleted = false;
        return this;
    }

    /// <summary>
    /// 设置元数据
    /// </summary>
    public File SetMetadata(string? metadata)
    {
        Metadata = metadata;
        return this;
    }

    /// <summary>
    /// 获取文件扩展名
    /// </summary>
    public virtual string? GetExtension()
    {
        if (string.IsNullOrEmpty(FileName))
        {
            return null;
        }

        var lastDotIndex = FileName.LastIndexOf('.');
        return lastDotIndex > 0 ? FileName.Substring(lastDotIndex) : null;
    }
}